package com.sahyadri.web.controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomBooleanEditor;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;

import com.sahyadri.web.bean.Category;
import com.sahyadri.web.bean.Events;
import com.sahyadri.web.bean.GalleryDetails;
import com.sahyadri.web.bean.Location;
import com.sahyadri.web.bean.Menu;
import com.sahyadri.web.bean.MenuEntry;
import com.sahyadri.web.bean.MenuSearchCriteria;
import com.sahyadri.web.bean.Offer;
import com.sahyadri.web.bean.Review;
import com.sahyadri.web.bean.SearchResults;
import com.sahyadri.web.enums.MaintenanceTabs;
import com.sahyadri.web.enums.SortColumn;
import com.sahyadri.web.util.DateTimeUtil;
import com.sahyadri.web.util.security.UserHolder;
import com.sahyadri.web.util.service.adpater.OrganizationServiceAdapter;
 
@Controller
@RequestMapping("/admin")
public class AdminController {
	private static final Logger LOG = Logger
			.getLogger(AdminController.class);
	
	@Autowired
	public OrganizationServiceAdapter organizationServiceAdapter;
	
	private UserHolder userHolder;
	
	@Autowired
	public void setUserHolder(UserHolder userHolder) {
		this.userHolder = userHolder;
	}
	
	@InitBinder
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(DateTimeUtil.DEFAULT_DATE_FORMAT);
		TimeZone timeZone = TimeZone.getTimeZone("IST");
		dateFormat.setTimeZone(timeZone);
		dateFormat.setLenient(true);
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
        binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));
        binder.registerCustomEditor(Boolean.class, null, new CustomBooleanEditor( "true", "false", true));
	}
	
	@RequestMapping(value="/landing", method = RequestMethod.GET)
	public String landingPage(@RequestParam(value = "tab", required = false) MaintenanceTabs tab, HttpSession session, ModelMap model) {
		
		LOG.debug("in landingPage ()");
		tab = (tab == null) ? MaintenanceTabs.LOCATION : tab;
		model.addAttribute("selectedTab", tab);
		setupLocationDetails(session, model);
		return "adminPageView";
 
	}
	
	private void setupLocationDetails(HttpSession session, ModelMap model) {
		List<Location> locations = organizationServiceAdapter.getAllLocations(userHolder.getUser().getOrganization());
		if(locations != null && locations.size() != 0 ) {
			if(session.getAttribute("selectedLocationId")!=null) {
				long selectedLocationId = getLocationIdFromSession(session);
				model.addAttribute("location", findLocation(locations, new Long(selectedLocationId)));
			}else{
				session.setAttribute("selectedLocationId", String.valueOf(locations.get(0).getId()));
				model.addAttribute("location", locations.get(0));
			}
			model.addAttribute("locations", locations);
			
		}else{
			model.addAttribute("locations", locations);
			model.addAttribute("location", new Location());
		}
		
	}
	
	@RequestMapping(value = "mask/location")
	public String maskOrg(@RequestParam("locationId") long locationId, HttpSession session, ModelMap model) {
		LOG.debug("Masking location id to " + locationId);
		session.setAttribute("selectedLocationId", String.valueOf(locationId));
		model.addAttribute("isSuccess", true);
		return "jsonView";
	}
	
	@RequestMapping(value = "/location")
	public String getLocationInfo(HttpSession session, ModelMap model) {
		LOG.debug("in getLocationInfo()");
		Location location = new Location();
		long locationId = getLocationIdFromSession(session);
		
		if(locationId == 0) {
			model.addAttribute("location", location);
			return "addLocationView";			
		}
		
		location = organizationServiceAdapter.getLocation(locationId);
		model.addAttribute("location", location);
		return "contactInfoView";
	
		
					
		
	}
	
	private Location findLocation(List<Location> locations, Long locationId) {
		for(Location location:locations) {
			if(locationId == location.getId()) {
				return location;
			}
		}
		return null;
	}
	@RequestMapping(value = "/location/add")
	public String setupNewLocationPage(HttpSession session, ModelMap model) {
		Location location = new Location();
		model.addAttribute("location", location);
		LOG.debug("in getContactInfo ()");
		return "addLocationView";
	}
	
	@RequestMapping(value = "/location/save")
	public String saveLocationDetails(Location location, ModelMap model) {

		LOG.debug("in saveLocationDetails()");
		location = organizationServiceAdapter.saveLocation(userHolder.getUser().getOrganization(), location);
		model.addAttribute("location", location);
		return "refreshPageFrag";
	}
	
	@RequestMapping(value = "/location/delete")
	public String deleteLocation(@RequestParam("locationId") long locationId, HttpSession session, ModelMap model) {
		LOG.debug("in deleteLocation () "+ locationId);
		
		organizationServiceAdapter.deleteLocation(userHolder.getUser().getOrganization(), locationId);
		long selectedLocationId = getLocationIdFromSession(session);
		if(selectedLocationId == locationId) {
			session.setAttribute("selectedLocationId", null);
		}
		return "refreshPageFrag";
	}
	
	
	@RequestMapping(value = "/menu")
	public String getMenuList(HttpSession session, ModelMap model) {
		LOG.debug("in getMenuList ()");
		if(!isLocationSelected(session)){
			return "locationNotAvailableInfoView";
		}
		long locationId = getLocationIdFromSession(session);
		List<Menu> menuList = organizationServiceAdapter.getMenuList(locationId);
		model.addAttribute("menuList", menuList);
		return "menuListView";
	}
	
	@RequestMapping(value = "/menu/add")
	public String setupNewMenuPage(HttpSession session, ModelMap model) {
		LOG.debug("in setupNewMenuPage ()");
		model.addAttribute("mode", "add");
		model.addAttribute("menu", new Menu());
		return "menuDetailsView";
	}
	
	@RequestMapping(value = "/menu/edit")
	public String setupEditMenuPage(@RequestParam("menuId") long menuId, HttpSession session, ModelMap model) {
		LOG.debug("in setupNewMenuPage ()");
		model.addAttribute("mode", "edit");
		model.addAttribute("menu", organizationServiceAdapter.getMenu(menuId));
		return "menuDetailsView";
	}
	
	@RequestMapping(value = "/menu/save")
	public String saveMenuDetails(Menu menu, HttpSession session, ModelMap model) {
		LOG.debug("in saveMenuDetails ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.saveMenu(locationId, menu);
		List<Menu> menuList = organizationServiceAdapter.getMenuList(locationId);
		model.addAttribute("menuList", menuList);
		return "menuListView";
	}
	
	@RequestMapping(value = "/menu/delete")
	public String deleteMenu(@RequestParam("menuId") long menuId, HttpSession session, ModelMap model) {
		LOG.debug("in deleteMenu ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.deleteMenu(locationId, menuId);
		List<Menu> menuList = organizationServiceAdapter.getMenuList(locationId);
		model.addAttribute("menuList", menuList);
		return "menuListView";
	}
	
	private long getLocationIdFromSession(HttpSession session ){
		String selectedLocationId = (String) session.getAttribute("selectedLocationId");
		if(StringUtils.hasText(selectedLocationId)){
			return new Long(selectedLocationId).longValue();
		}
		return 0;
	}
	
	private boolean isLocationSelected(HttpSession session){
		if(session.getAttribute("selectedLocationId")!=null){
			return true;
		}
		return false;
	}
	@RequestMapping(value = "/category")
	public String getMenuCategory(HttpSession session, ModelMap model) {
		LOG.debug("in getMenuCategory ()");
		if(!isLocationSelected(session)){
			return "locationNotAvailableInfoView";
		}
		long locationId = getLocationIdFromSession(session);
		List<Category> categoryList = organizationServiceAdapter.getCategoryList(locationId);
		model.addAttribute("categoryList", categoryList);
		return "categoryListView";
	}
	
	
	@RequestMapping(value = "/category/add")
	public String setupNewCategoryPage(HttpSession session, ModelMap model) {
		LOG.debug("in setupNewCategoryPage ()");
		
		model.addAttribute("mode", "add");
		model.addAttribute("category", new Category());
		return "categoryDetailsView";
	}
	
	@RequestMapping(value = "/category/edit")
	public String setupEditCatgeoryPage(@RequestParam("categoryId") long categoryId, 
			HttpSession session, ModelMap model) {
		LOG.debug("in setupEditCatgeoryPage ()");
				
		model.addAttribute("mode", "edit");
		model.addAttribute("category", organizationServiceAdapter.getCategory(categoryId));
		return "categoryDetailsView";
	}
	
	@RequestMapping(value = "/category/assignmenus")
	public String setupAssignMenusPage(@RequestParam("categoryId") long categoryId,
			HttpSession session, ModelMap model) {
		
		LOG.debug("in setupAssignMenusPage ()");
		model.addAttribute("category", organizationServiceAdapter.getCategory(categoryId));
		return "assingMenuView";
	}
	
	@RequestMapping(value = "/category/menu/list")
	public String setupCategoryMenuList(@RequestParam("categoryId") long categoryId, ModelMap model){
		LOG.debug("Hit setupCategoryMenuList()");
		List<MenuEntry> menuList = organizationServiceAdapter.getCategoryMenuList(categoryId);
		model.addAttribute("menuList", menuList);
		
		
		return "jsonView";
	}
	
	
	@RequestMapping(value = "/category/assignmenus/save")
	public String saveMenucategory(@RequestParam("categoryId") long categoryId,
			@RequestParam("menuId") long menuId, 
			HttpSession session, ModelMap model) {
		LOG.debug("in saveMenucategory ()");
		MenuEntry categoryMenuEntry = new MenuEntry();
		categoryMenuEntry.setMenu(organizationServiceAdapter.assignMenu(categoryId, menuId));
		model.addAttribute("categoryMenuEntry", categoryMenuEntry);
		model.addAttribute("isSuccess", true);
		
		return "jsonView";
	}
	
	
	@RequestMapping(value = "category/menu/quickSearch")
	public String searchStatesAutoCompleteHandler(@RequestParam(value = "query", required = true) String query,
			@RequestParam(value = "searchType", required = true) String searchType,
			ModelMap model) {
		LOG.debug("Searching for state with following query: " + query);
		MenuSearchCriteria criteria = new MenuSearchCriteria();
		criteria.setSearchType(searchType);
		criteria.setSearchQuery(query);
		
		criteria.setPageSize(10);
		criteria.setStartIndex(0);
		criteria.setSortColumn(SortColumn.CODE);

		SearchResults<MenuEntry> results = organizationServiceAdapter.searchMenus(criteria);
		model.addAttribute("results", results);
		return "jsonView";
	}
	
	@RequestMapping(value = "/category/save")
	public String saveCategoryDetails(Category category, HttpSession session, ModelMap model) {
		LOG.debug("in saveCategoryDetails ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.saveCategory(locationId, category);
		List<Category> categoryList = organizationServiceAdapter.getCategoryList(locationId);
		model.addAttribute("categoryList", categoryList);
		return "categoryListView";
	}
	
	@RequestMapping(value = "/category/delete")
	public String deleteCategory(@RequestParam("categoryId") long categoryId, HttpSession session, ModelMap model) {
		LOG.debug("in deleteCategory ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.deleteCategory(locationId, categoryId);
		List<Category> categoryList = organizationServiceAdapter.getCategoryList(locationId);
		model.addAttribute("categoryList", categoryList);
		return "categoryListView";
	}
	@RequestMapping(value = "/reviews")
	public String getReviewList(HttpSession session, ModelMap model) {
		LOG.debug("in getReviewList ()");
		if(!isLocationSelected(session)){
			return "locationNotAvailableInfoView";
		}
		long locationId = getLocationIdFromSession(session);
		List<Review> reviewList = organizationServiceAdapter.getReviewList(locationId);
		model.addAttribute("reviewList",reviewList);
		return "reviewListView";
	}
	
	@RequestMapping(value = "/reviews/add")
	public String setupNewReviewPage(HttpSession session, ModelMap model) {
		LOG.debug("in setupNewReviewPage ()");
		model.addAttribute("mode", "add");
		model.addAttribute("review", new Review());
		return "reviewDetailsView";
	}
	
	@RequestMapping(value = "/reviews/edit")
	public String setupEditReviewPage(@RequestParam("reviewId") long reviewId, HttpSession session, ModelMap model) {
		LOG.debug("in setupEditReviewPage ()");
		model.addAttribute("mode", "edit");
		model.addAttribute("review", organizationServiceAdapter.getReview(reviewId));
		return "reviewDetailsView";
	}
	
	@RequestMapping(value = "/reviews/save")
	public String saveReviewDetails(Review review, HttpSession session, ModelMap model) {
		LOG.debug("in saveReviewDetails ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.saveReview(locationId, review);
		List<Review> reviewList = organizationServiceAdapter.getReviewList(locationId);
		model.addAttribute("reviewList",reviewList);
		return "reviewListView";
	}
	
	@RequestMapping(value = "/reviews/delete")
	public String deleteReviews(@RequestParam("reviewId") long reviewId, HttpSession session, ModelMap model) {
		LOG.debug("in deleteReviews ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.deleteReview(locationId, reviewId);
		List<Review> reviewList = organizationServiceAdapter.getReviewList(locationId);
		model.addAttribute("reviewList",reviewList);
		return "reviewListView";
	}

	@RequestMapping(value = "/events")
	public String getEventList(HttpSession session, ModelMap model) {
		LOG.debug("in getEventList ()");
		if(!isLocationSelected(session)){
			return "locationNotAvailableInfoView";
		}
		long locationId = getLocationIdFromSession(session);
		List<Events> eventList = organizationServiceAdapter.getEventList(locationId);
		model.addAttribute("eventList", eventList);
		return "eventListView";
	}
	
	@RequestMapping(value = "/event/add")
	public String setupNewEventPage(HttpSession session, ModelMap model) {
		LOG.debug("in setupNewEventPage ()");
		model.addAttribute("mode", "add");
		model.addAttribute("event", new Events());
		return "eventDetailsView";
	}
	
	@RequestMapping(value = "/event/edit")
	public String setupEditEventPage(@RequestParam("eventId") long eventId, HttpSession session, ModelMap model) {
		LOG.debug("in setupEditEventPage ()");
		model.addAttribute("mode", "edit");
		model.addAttribute("event", organizationServiceAdapter.getEvent(eventId));
		return "eventDetailsView";
	}
	
	@RequestMapping(value = "/event/save")
	public String saveEventDetails(Events event, @RequestParam("action") String action, HttpSession session, ModelMap model) {
		LOG.debug("in saveEventDetails ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.saveEvent(locationId, event, action);
		List<Events> eventList = organizationServiceAdapter.getEventList(locationId);
		model.addAttribute("eventList", eventList);
		return "eventListView";
	}
	
	@RequestMapping(value = "/event/delete")
	public String deleteEventPage(@RequestParam("eventId") long eventId, HttpSession session, ModelMap model) {
		LOG.debug("in setupNewOfferPage ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.deleteEvent(locationId, eventId);
		List<Events> eventList = organizationServiceAdapter.getEventList(locationId);
		model.addAttribute("eventList", eventList);
		return "eventListView";
	}
	
	@RequestMapping(value = "/offers")
	public String getOfferList(HttpSession session, ModelMap model) {
		LOG.debug("in getOfferList ()");
		if(!isLocationSelected(session)){
			return "locationNotAvailableInfoView";
		}
		long locationId = getLocationIdFromSession(session);
		List<Offer> offerList = organizationServiceAdapter.getOfferList(locationId);
		model.addAttribute("offerList", offerList);
		return "offerListView";
	}
	
	@RequestMapping(value = "/offer/add")
	public String setupNewOfferPage(HttpSession session, ModelMap model) {
		LOG.debug("in setupNewOfferPage ()");
		model.addAttribute("mode", "add");
		model.addAttribute("offer", new Offer());
		return "offerDetailsView";
	}
	
	@RequestMapping(value = "/offer/edit")
	public String setupEditOfferPage(@RequestParam("offerId") long offerId, HttpSession session, ModelMap model) {
		LOG.debug("in setupEditOfferPage ()");
		model.addAttribute("mode", "edit");
		model.addAttribute("offer", organizationServiceAdapter.getOffer(offerId));
		return "offerDetailsView";
	}
	
	@RequestMapping(value = "/offer/save")
	public String saveOfferDetails(Offer offer, HttpSession session, ModelMap model) {
		LOG.debug("in saveOfferDetails ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.saveOffer(locationId, offer);
		List<Offer> offerList = organizationServiceAdapter.getOfferList(locationId);
		model.addAttribute("offerList", offerList);
		return "offerListView";
	}
	@RequestMapping(value = "/offer/delete")
	public String deleteOffer(@RequestParam("offerId") long offerId, HttpSession session, ModelMap model) {
		LOG.debug("in deleteOffer ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.deleteOffer(locationId, offerId);
		List<Offer> offerList = organizationServiceAdapter.getOfferList(locationId);
		model.addAttribute("offerList", offerList);
		return "offerListView";
	}

	@RequestMapping(value = "/gallery")
	public String getPhotoGalleryList(HttpSession session, ModelMap model) {
		LOG.debug("in getPhotoGalleryList ()");
		if(!isLocationSelected(session)){
			return "locationNotAvailableInfoView";
		}
		long locationId = getLocationIdFromSession(session);
		List<GalleryDetails> galleryList = organizationServiceAdapter.getGalleryList(locationId);
		model.addAttribute("galleryList", galleryList);
		return "photoGalleryListView";
	}
	
	@RequestMapping(value = "/gallery/add")
	public String setupNewGalleryPage(HttpSession session, ModelMap model) {
		LOG.debug("in setupNewOfferPage ()");
		model.addAttribute("mode", "add");
		model.addAttribute("gallery", new GalleryDetails());
		return "photoGalleryDetailsView";
	}
	
	@RequestMapping(value = "/gallery/delete")
	public String deleteGalleryPage(@RequestParam("galleryId") long galleryId, HttpSession session, ModelMap model) {
		LOG.debug("in setupNewOfferPage ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.deleteGallery(locationId, galleryId);
		List<GalleryDetails> galleryList = organizationServiceAdapter.getGalleryList(locationId);
		model.addAttribute("galleryList", galleryList);
		return "photoGalleryListView";
	}
	
	@RequestMapping(value = "/gallery/edit")
	public String setupEditGalleryPage(@RequestParam("galleryId") long galleryId, HttpSession session, ModelMap model) {
		LOG.debug("in setupEditOfferPage ()");
		model.addAttribute("mode", "edit");
		model.addAttribute("gallery", organizationServiceAdapter.getGallery(galleryId));
		return "photoGalleryDetailsView";
	}
	
	@RequestMapping(value = "/gallery/save")
	public String saveGalleryDetails(GalleryDetails gallery, HttpSession session, ModelMap model) {
		LOG.debug("in saveOfferDetails ()");
		long locationId = getLocationIdFromSession(session);
		organizationServiceAdapter.saveGallery(locationId, gallery);
		List<GalleryDetails> galleryList = organizationServiceAdapter.getGalleryList(locationId);
		model.addAttribute("galleryList", galleryList);
		return "photoGalleryListView";
	}
	
	
 
	
 
}